package com.eobard.utils;

import cn.hutool.core.util.RandomUtil;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.type.Type;

import java.util.*;

/**
 * @Author: divenswu
 * @Date: 2025-04-22
 * @Description: 随机参数表达式
 */
public class RandomExpression {
    public static final String println = "loggerPrint";
    private static final Random random = new Random();
    private static final String baseString = "ghjkmnoqrtuwxyz";

    public static Type randomType() {
        String[] types = {"int", "String", "boolean", "double", "float", "long", "Object"};
        return StaticJavaParser.parseType(types[random.nextInt(types.length)]);
    }

    public static String getName() {
        String baseName = RandomUtil.randomString(baseString, random.nextInt(3) + 1);
        return baseName + RandomUtil.randomString(random.nextInt(6) + 1);
    }

    //设置常量字段的名称
    public static String getStaticFinalFiledName() {
        String baseCharUpperCase = RandomUtil.BASE_CHAR_NUMBER_LOWER.toUpperCase();
        int length = random.nextInt(4) + 4;
        String prefix = RandomUtil.randomString(baseCharUpperCase, length);
        while (Character.isDigit(prefix.charAt(0))) {
            prefix = RandomUtil.randomString(baseCharUpperCase, length);
        }
        String suffix = RandomUtil.randomString(baseCharUpperCase, length);
        return prefix + "_" + suffix;
    }

    public static String className() {
        return RandomUtil.randomString(baseString, 1).toUpperCase() + getName();
    }

    public static String getLoggerPrintName() {
        return println;
    }

    public static Expression generateValue(String type) {
        switch (type) {
            case "double":
                return new DoubleLiteralExpr(Double.valueOf(random.nextDouble() * 1000).intValue() / 100d);
            case "boolean":
                return new BooleanLiteralExpr(random.nextBoolean());
            case "int":
                return new IntegerLiteralExpr(String.valueOf(random.nextInt(1000)));
            case "String":
                return new StringLiteralExpr(RandomUtil.randomString(random.nextInt(10) + 1));
            case "float":
                return new IntegerLiteralExpr(String.valueOf(random.nextInt(20000)));
            case "long":
                return new IntegerLiteralExpr(String.valueOf(random.nextInt(10000)));
            default:
                return new NullLiteralExpr();
        }
    }

    public static List<Statement> generateStatement(Map<String, String> params) {
        List<Statement> statements = new ArrayList<>(params.size());
        for (String name : params.keySet()) {
            String type = params.get(name);
            if ("String".equalsIgnoreCase(type)) {
                statements.addAll(getStringGenerateStatement(name, params));
            } else if ("int".equalsIgnoreCase(type)) {
                statements.addAll(getIntegerGenerateStatement(name, params));
            } else if ("long".equalsIgnoreCase(type)) {
                statements.addAll(getLongGenerateStatement(name, params));
            } else if ("float".equalsIgnoreCase(type)) {
                statements.addAll(getFloatGenerateStatement(name, params));
            } else if ("double".equalsIgnoreCase(type)) {
                statements.addAll(getDoubleGenerateStatement(name, params));
            } else if ("boolean".equalsIgnoreCase(type)) {
                statements.addAll(getBooleanGenerateStatement(name, params));
            } else {
                statements.addAll(getObjectGenerateStatement(name, params));
            }
        }
        return statements;
    }

    private static List<Statement> getStringGenerateStatement(String name, Map<String, String> params) {
        List<Statement> statements = new ArrayList<>();
        if (random.nextInt(10) > 5) {
            String code = name + " = " + name + " + \"" + RandomUtil.randomString(random.nextInt(10) + 1) + "\";\n";
            statements.add(StaticJavaParser.parseStatement(code));
        }
        statements.add(StaticJavaParser.parseStatement(println + "(\"value=\"+" + name + "+\",rs=" + random.nextInt(20000) + "\");"));
        return statements;
    }

    private static List<Statement> getIntegerGenerateStatement(String name, Map<String, String> params) {
        int tp1 = random.nextInt(1000);
        int tp2 = random.nextInt(1000) + tp1 + 10;
        StringBuilder sb = new StringBuilder();
        if (random.nextInt(10) > 5) {
            sb.append("if(").append(name).append(" > ").append(tp1).append("){");
        } else {
            sb.append("if(").append(name).append(" > ").append(tp1).append("&& ").append(name).append(" < ").append(tp2).append("){");
        }
        if (random.nextInt(10) > 5) {
            sb.append(name).append(" = ").append(name).append(" + ").append(tp1).append(" - ").append(random.nextInt(200)).append(";");
        } else {
            sb.append(name).append(" = ").append(name).append(" + ").append(tp1).append(" + ").append(random.nextInt(200)).append(";");
        }
        if (random.nextInt(10) > 5) {
            sb.append(println + "(\"name=\"+").append(name).append(");");
        } else {
            sb.append(println + "(\"data=\"+").append(name).append(");");
        }
        if (random.nextInt(10) > 5) {
            sb.append("}");
        } else {
            sb.append("} else {");
            sb.append(println + "(\"value=\"+").append(random.nextInt(20000)).append(");");
            sb.append("}");
        }
        return Collections.singletonList(StaticJavaParser.parseStatement(sb.toString()));
    }

    private static List<Statement> getLongGenerateStatement(String name, Map<String, String> params) {
        long tp1 = random.nextInt(1000);
        long tp2 = random.nextInt(2000) + tp1 + 88;
        StringBuilder sb = new StringBuilder();
        if (random.nextInt(10) > 5) {
            sb.append("if(").append(name).append(" < ").append(tp1).append("){");
        } else {
            sb.append("if(").append(name).append(" < ").append(tp1).append(" || ").append(name).append(" > ").append(tp2).append("){");
        }
        if (random.nextInt(10) > 5) {
            sb.append(name).append(" = ").append(name).append(" + ").append(tp1).append(" - ").append(random.nextInt(200)).append(";");
        } else {
            sb.append(name).append(" = ").append(name).append(" + ").append(tp1).append(" * ").append(random.nextInt(200)).append(";");
        }
        if (random.nextInt(10) > 6) {
            sb.append(println + "(\"name=\"+").append(name).append(");");
        } else {
            sb.append(println + "(\"data=\"+").append(name).append(");");
        }
        if (random.nextInt(10) > 5) {
            sb.append("}");
        } else {
            sb.append("} else {");
            sb.append(println + "(\"value=\"+").append(random.nextInt(20000)).append(");");
            sb.append("}");
        }
        return Collections.singletonList(StaticJavaParser.parseStatement(sb.toString()));
    }

    private static List<Statement> getFloatGenerateStatement(String name, Map<String, String> params) {
        List<Statement> statements = new ArrayList<>();
        String paramAName = getName();
        statements.add(StaticJavaParser.parseStatement("float " + paramAName + " = " + random.nextFloat() + "f;"));
        StringBuilder sb = new StringBuilder();
        sb.append("for(int iyy=0; iyy<" + random.nextInt(5) + "+2; iyy++){");
        sb.append(paramAName + " = " + paramAName + " + " + random.nextFloat() + "f;");
        sb.append("}");
        statements.add(StaticJavaParser.parseStatement(sb.toString()));
        statements.add(StaticJavaParser.parseStatement(paramAName + " = " + paramAName + " + " + name + ";"));
        statements.add(StaticJavaParser.parseStatement(println + "(\"data=\"+" + paramAName + ");"));
        return statements;
    }

    private static List<Statement> getDoubleGenerateStatement(String name, Map<String, String> params) {
        List<Statement> statements = new ArrayList<>();
        String paramAName = name;
        StringBuilder sb = new StringBuilder();
        sb.append("for(int ixx=0; ixx<" + random.nextInt(5) + "+2; ixx++){");
        sb.append(paramAName + " = " + paramAName + " + " + random.nextFloat() + 1 + "d;");
        sb.append("}");
        statements.add(StaticJavaParser.parseStatement(sb.toString()));
        statements.add(StaticJavaParser.parseStatement(println + "(\"count=\"+" + paramAName + ");"));
        return statements;
    }

    private static List<Statement> getBooleanGenerateStatement(String name, Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        if (random.nextInt(10) > 5) {
            sb.append("if(").append(name).append("){");
        } else {
            sb.append("if(!").append(name).append("){");
        }
        if (random.nextInt(8) > 4) {
            sb.append(println + "(\"name=\"+").append(name).append(");");
        } else {
            sb.append(println + "(\"data=\"+").append(name).append(");");
        }
        if (random.nextInt(10) > 5) {
            sb.append("}");
        } else {
            sb.append("} else {");
            sb.append(println + "(\"value=\"+").append(random.nextInt(60000)).append(");");
            sb.append("}");
        }
        return Collections.singletonList(StaticJavaParser.parseStatement(sb.toString()));
    }

    public static List<Statement> getObjectGenerateStatement(String name, Map<String, String> params) {
        List<Statement> statements = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        String paramAName = getName();
        String paramBName = getName();
        statements.add(StaticJavaParser.parseStatement("int " + paramAName + " = " + random.nextInt(100000) + ";"));
        statements.add(StaticJavaParser.parseStatement("int " + paramBName + " = " + random.nextInt(100000) + ";"));
        sb.append("if(").append(paramAName).append(">").append(paramBName).append("){");
        sb.append(println + "(\"value=\"+(").append(paramAName).append("*").append(paramBName).append("));");
        sb.append("}");
        statements.add(StaticJavaParser.parseStatement(sb.toString()));
        return statements;
    }
}

